﻿using Ldt.DataEngine.LogHandle;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace LdtJudge.DataEngine.CallInterface.FileManager
{
    /// <summary>
    /// 获取文件的地址
    /// </summary>
    public class GetHttpDataFile
    {
        /// <summary>
        ///     根据文件的ID进行获取文件
        /// </summary>
        /// <param name="FileCode">文件ID</param>
        /// <param name="OutRealtID">案件唯一ID</param>
        /// <returns></returns>
        private static string GetHttpDataText(string FileCode, string caseid, string OutRealtID = "")
        {
            // 创建一个HTTP请求  
            var strURL = ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("FileManager") + "/filesv/v1/file/{0}?caseid=" + OutRealtID;
            var url = string.Format(strURL, FileCode);
            LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】为调用获取文件的地址为：" + url);
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "get";
            var response = (HttpWebResponse)request.GetResponse();
            var myreader = new StreamReader(response.GetResponseStream());
            var responseText = myreader.ReadToEnd();
            LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】调用Json结果：" + responseText);
            myreader.Close();
            return responseText;
        }


        /// <summary>
        ///     根据文件code 返回本地的文件存储位置
        /// </summary>
        /// <param name="filecode"></param>
        /// <param name="filepath"></param>
        /// <returns></returns>
        [Obsolete("该方法已经启用", true)]
        public static string GetHttpDtataFilePah(string filecode, string filepath, string caseid)
        {
            var jsonstr = string.Empty;
            try
            {
                jsonstr = GetHttpDataText(filecode, caseid);
            }
            catch (Exception ex)
            {
                LogHandle.GetInitLogHandle.LogWrite("进行调用获取文件对象的字符串，输入的文件为ID为：" + filecode + "  错误消息为：" + ex.Message);
                LogHandle.GetInitLogHandle.LogWrite("进行调用获取文件对象的字符串，输入的文件为ID为：" + filecode + "  错误消息为：" + ex.StackTrace);
            }
            if (!string.IsNullOrWhiteSpace(jsonstr))
            {
                var model = JsonConvert.DeserializeObject<Rootobject>(jsonstr);
                LogHandle.GetInitLogHandle.LogWrite("转换对象：" + JsonConvert.SerializeObject(model));
                if (model.Body != null && model.Body.Length > 0)
                {
                    //model.Body[0].FileUrl; //文件地址
                    //model.Body[0].Name; //文件名称
                    //model.Body[0].Ext; //后缀名
                    string filename = Guid.NewGuid().ToString("N");
                    return DownLoadFile(model.Body[0].FileUrl, filepath, filename, model.Body[0].Ext.ToLower());
                }
                else
                {
                    LogHandle.GetInitLogHandle.LogWrite("根据文件的code获取文件的返回对象中不存在bodyd对象，输入的文件code为ID为：" + filecode + "  获取到返回的内容为：" + jsonstr);
                }
            }
            else
            {
                LogHandle.GetInitLogHandle.LogWrite("根据文件的code获取文件的返回字符串出现问题，输入的文件code为ID为：" + filecode + "  获取到返回的内容为：" + jsonstr);
            }
            return "";
        }

        /// <summary>
        ///     根据文件code 返回本地的文件存储位置
        /// </summary>
        /// <param name="filecode">云存储ID</param>
        /// <param name="filepath">文件存储路径</param>
        /// <param name="OutRealtID">当前案件的唯一ID</param>
        /// <returns></returns>
        public static string GetHttpDtataFilePah(string filecode, string filepath, string caseid, string OutRealtID)
        {
            var jsonstr = string.Empty;
            try
            {
                jsonstr = GetHttpDataText(filecode, caseid, OutRealtID);
            }
            catch (Exception ex)
            {
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】进行调用获取文件对象的字符串，输入的文件为ID为：" + filecode + "  错误消息为：" + ex.Message);
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】进行调用获取文件对象的字符串，输入的文件为ID为：" + filecode + "  错误消息为：" + ex.StackTrace);
            }
            if (!string.IsNullOrWhiteSpace(jsonstr))
            {
                var model = JsonConvert.DeserializeObject<Rootobject>(jsonstr);
                LogHandle.GetInitLogHandle.LogWrite("转换对象：" + JsonConvert.SerializeObject(model));
                if (model.Body != null && model.Body.Length > 0)
                {
                   
                    string filename = Guid.NewGuid().ToString("N");
                    return DownLoadFile(model.Body[0].FileUrl, filepath, filename, model.Body[0].Ext.ToLower(), OutRealtID);
                }
                else
                {
                    LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据文件的code获取文件的返回对象中不存在bodyd对象，输入的文件code为ID为：" + filecode + "  获取到返回的内容为：" + jsonstr);
                }
            }
            else
            {
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据文件的code获取文件的返回字符串出现问题，输入的文件code为ID为：" + filecode + "  获取到返回的内容为：" + jsonstr);
            }
            return "";
        }

       
        /// <summary>
        /// 进行下载文件
        /// </summary>
        /// <param name="FielUrl">根据URL进行获取到文件流</param>
        /// <param name="FilePath">需要保存的文件路径</param>
        /// <param name="FileName">文件名称</param>
        /// <param name="Fileext">文件的后缀名称</param>
        /// <param name="OutRealtID">案件关联ID</param>
        /// <returns></returns>
        private static string DownLoadFile(string FielUrl, string FilePath, string FileName, string Fileext, string OutRealtID = "")
        {
            if (!System.IO.Directory.Exists(FilePath))
            {//判断当前目录是否存在，如果不存在则创建
                System.IO.Directory.CreateDirectory(FilePath);
            }
            string extfile = "." + Fileext.TrimStart('.');
            string fileTemp = FilePath + FileName + extfile;
            int i = 1;
            while (System.IO.File.Exists(fileTemp))
            {//如果当前路径存在则进行重新命名
                fileTemp = FilePath + FileName + "（" + i + "）" + extfile;
                i++;
                //System.IO.File.Delete(FilePath);
            }

            Stream st = null;
            try
            {
                WebClient wb = new WebClient();
                byte[] bytes = wb.DownloadData(FielUrl);
                st = new MemoryStream(bytes);
                wb.Dispose();
            }
            catch (Exception ex)
            {
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据文件的URL获取文件流出现问题，错误消息为：" + ex.Message);
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据文件的URL获取文件流出现问题，错误消息为：" + ex.StackTrace);
                fileTemp = string.Empty;
            }
            try
            {
                if (st.Length <= 0)
                {
                    LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】返回流文件有问题流长度为0");
                    fileTemp = string.Empty;
                }
                StreamWriter sw = new StreamWriter(fileTemp);
                st.CopyTo(sw.BaseStream);
                sw.Flush();
                sw.Close();
            }
            catch (Exception ex)
            {
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据流文件进行转换成本地文件路径出现问题，错误消息为：" + ex.Message);
                LogHandle.GetInitLogHandle.LogWrite($"当前案件唯一ID【{OutRealtID}】根据流文件进行转换成本地文件路径出现问题，错误消息为：" + ex.StackTrace);
                fileTemp = string.Empty;
            }
            return fileTemp;
        }


        #region 文件下载方法

        /// <summary>
        /// http下载文件
        /// </summary>
        /// <param name="url">下载文件地址</param>
        /// <param name="path">文件存放地址，包含文件名</param>
        /// <returns></returns>
        public bool HttpDownload(string url, string path)
        {
            string tempPath = System.IO.Path.GetDirectoryName(path) + @"\temp";
            System.IO.Directory.CreateDirectory(tempPath);  //创建临时文件目录
            string tempFile = tempPath + @"\" + System.IO.Path.GetFileName(path) + ".temp"; //临时文件
            if (System.IO.File.Exists(tempFile))
            {
                System.IO.File.Delete(tempFile);    //存在则删除
            }
            try
            {
                FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                // 设置参数
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();
                //创建本地文件写入流
                byte[] bArr = new byte[1024];
                int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                while (size > 0)
                {
                    fs.Write(bArr, 0, size);
                    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                }
                fs.Close();
                responseStream.Close();
                System.IO.File.Move(tempFile, path);
                return true;
            }
            catch
            {
                return false;
            }
        }


        /// <summary>
        /// Http方式下载文件
        /// </summary>
        /// <param name="url">http地址</param>
        /// <param name="localfile">本地文件</param>
        /// <returns></returns>
        public bool Download(string url, string localfile)
        {
            bool flag = false;
            long startPosition = 0; // 上次下载的文件起始位置
            FileStream writeStream; // 写入本地文件流对象

            long remoteFileLength = GetHttpLength(url);// 取得远程文件长度
            System.Console.WriteLine("remoteFileLength=" + remoteFileLength);
            if (remoteFileLength == 745)
            {
                System.Console.WriteLine("远程文件不存在.");
                return false;
            }

            // 判断要下载的文件夹是否存在
            if (File.Exists(localfile))
            {

                writeStream = File.OpenWrite(localfile);             // 存在则打开要下载的文件
                startPosition = writeStream.Length;                  // 获取已经下载的长度

                if (startPosition >= remoteFileLength)
                {
                    System.Console.WriteLine("本地文件长度" + startPosition + "已经大于等于远程文件长度" + remoteFileLength);
                    writeStream.Close();

                    return false;
                }
                else
                {
                    writeStream.Seek(startPosition, SeekOrigin.Current); // 本地文件写入位置定位
                }
            }
            else
            {
                writeStream = new FileStream(localfile, FileMode.Create);// 文件不保存创建一个文件
                startPosition = 0;
            }


            try
            {
                HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(url);// 打开网络连接

                if (startPosition > 0)
                {
                    myRequest.AddRange((int)startPosition);// 设置Range值,与上面的writeStream.Seek用意相同,是为了定义远程文件读取位置
                }


                Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流


                byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容
                int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次

                long currPostion = startPosition;

                while (contentSize > 0)// 如果读取长度大于零则继续读
                {
                    currPostion += contentSize;
                    int percent = (int)(currPostion * 100 / remoteFileLength);
                    System.Console.WriteLine("percent=" + percent + "%");

                    writeStream.Write(btArray, 0, contentSize);// 写入本地文件
                    contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取
                }

                //关闭流
                writeStream.Close();
                readStream.Close();

                flag = true;        //返回true下载成功
            }
            catch (Exception)
            {
                writeStream.Close();
                flag = false;       //返回false下载失败
            }

            return flag;
        }

        // 从文件头得到远程文件的长度
        private static long GetHttpLength(string url)
        {
            long length = 0;

            try
            {
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);// 打开网络连接
                HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();

                if (rsp.StatusCode == HttpStatusCode.OK)
                {
                    length = rsp.ContentLength;// 从文件头得到远程文件的长度
                }

                rsp.Close();
                return length;
            }
            catch
            {
                return length;
            }

        }
        #endregion



    }
}
